import streamlit as st
import pandas as pd
import plotly.express as px
from datetime import datetime
from collections import defaultdict
import re
import glob
import os

class ErrorRecordsView:
    """错误记录视图类"""
    
    def __init__(self):
        pass
    
    def render(self):
        """渲染错误记录页面"""
        st.header("错误记录")
        
        try:
            # 从日志文件中提取错误信息
            current_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
            log_path = os.path.join(current_dir, "logs")
            log_files = glob.glob(log_path + "/debug_*.log")
            if not log_files:
                st.warning("📄 未找到日志文件")
                return
            
            # 读取最新的几个日志文件
            log_files.sort(key=os.path.getctime, reverse=True)
            recent_log_files = log_files[:5]  # 最近5个日志文件

            error_records = []
            error_types = defaultdict(int)
            
            for log_file in recent_log_files:
                try:
                    with open(log_file, 'r', encoding='utf-8') as f:
                        lines = f.readlines()
                        
                    for line in lines:
                        if 'ERROR' in line:
                            # 解析错误信息
                            timestamp_match = re.search(r'(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2})', line)
                            timestamp = timestamp_match.group(1) if timestamp_match else "未知时间"
                            
                            # 提取邮件UID或委托单号
                            uid_match = re.search(r'邮件[：:]?\s*([^，,\s]+)', line)
                            wt_match = re.search(r'委托单号[：:]?\s*([^，,\s]+)', line)
                            
                            email_id = ""
                            if uid_match:
                                email_id = uid_match.group(1)
                            elif wt_match:
                                email_id = wt_match.group(1)
                            else:
                                # 尝试提取其他标识符
                                id_match = re.search(r'[：:]\s*([A-Za-z0-9]+)', line)
                                if id_match:
                                    email_id = id_match.group(1)
                            
                            # 分类错误类型
                            error_type = "其他错误"
                            if '连接' in line or '网络' in line:
                                error_type = "网络连接错误"
                            elif '认证' in line or '密码' in line or '登录' in line:
                                error_type = "认证错误"
                            elif '解析' in line or '格式' in line:
                                error_type = "数据解析错误"
                            elif '超时' in line:
                                error_type = "超时错误"
                            elif '权限' in line:
                                error_type = "权限错误"
                            elif '获取邮件失败' in line:
                                error_type = "邮件获取失败"
                            elif '处理邮件' in line and '失败' in line:
                                error_type = "邮件处理失败"
                            
                            error_types[error_type] += 1
                            
                            error_records.append({
                                '时间': timestamp,
                                '邮件标识': email_id,
                                '错误类型': error_type,
                                '错误详情': line.strip()
                            })
                            
                except Exception as e:
                    st.warning(f"读取日志文件 {log_file} 时出错: {str(e)}")
                    continue
            
            # 错误统计概览
            st.subheader("📊 错误统计概览")
            
            col1, col2, col3, col4 = st.columns(4)
            
            with col1:
                st.metric("总错误数", len(error_records))
            
            with col2:
                st.metric("错误类型数", len(error_types))
            
            with col3:
                # 今日错误数
                today = datetime.now().strftime('%Y-%m-%d')
                today_errors = [r for r in error_records if today in r['时间']]
                st.metric("今日错误", len(today_errors))
            
            with col4:
                # 最近错误时间
                if error_records:
                    latest_error = max(error_records, key=lambda x: x['时间'])
                    latest_time = latest_error['时间'].split(' ')[1] if ' ' in latest_error['时间'] else latest_error['时间']
                    st.metric("最近错误时间", latest_time)
                else:
                    st.metric("最近错误时间", "无")
            
            # 错误类型分布
            if error_types:
                st.subheader("🔍 错误类型分布")
                
                col1, col2 = st.columns(2)
                
                with col1:
                    # 错误类型饼图
                    fig_pie = px.pie(
                        values=list(error_types.values()),
                        names=list(error_types.keys()),
                        title="错误类型分布"
                    )
                    st.plotly_chart(fig_pie, use_container_width=True)
                
                with col2:
                    # 错误类型统计表
                    error_type_df = pd.DataFrame(
                        list(error_types.items()),
                        columns=['错误类型', '出现次数']
                    ).sort_values('出现次数', ascending=False)
                    st.dataframe(error_type_df, use_container_width=True)
            
            st.divider()
            
            # 错误记录详情表
            st.subheader("错误记录详情")
            
            # 添加筛选选项
            col1, col2 = st.columns(2)
            with col1:
                selected_error_types = st.multiselect(
                    "筛选错误类型",
                    options=list(error_types.keys()),
                    default=list(error_types.keys())
                )
            with col2:
                search_term = st.text_input("搜索邮件标识或错误详情")
            
            # 过滤数据
            filtered_records = error_records
            if selected_error_types:
                filtered_records = [r for r in filtered_records if r['错误类型'] in selected_error_types]
            if search_term:
                filtered_records = [r for r in filtered_records if 
                                  search_term.lower() in r['邮件标识'].lower() or 
                                  search_term.lower() in r['错误详情'].lower()]
            
            # 显示过滤后的记录
            if filtered_records:
                df_errors = pd.DataFrame(filtered_records)
                st.dataframe(df_errors, use_container_width=True)
                
                # 导出功能
                if st.button("📥 导出错误记录"):
                    csv = df_errors.to_csv(index=False, encoding='utf-8-sig')
                    st.download_button(
                        label="下载CSV文件",
                        data=csv,
                        file_name=f"error_records_{datetime.now().strftime('%Y%m%d_%H%M%S')}.csv",
                        mime="text/csv"
                    )
            else:
                st.info("🔍 没有符合筛选条件的错误记录")
            
            # 时间趋势分析
            st.subheader("错误时间趋势")
            if error_records:
                # 按小时统计错误
                hourly_errors = defaultdict(int)
                for record in error_records:
                    try:
                        hour = record['时间'].split(' ')[1].split(':')[0]
                        hourly_errors[f"{hour}:00"] += 1
                    except:
                        continue
                
                if hourly_errors:
                    hourly_df = pd.DataFrame(list(hourly_errors.items()), columns=['时间', '错误数量'])
                    hourly_df = hourly_df.sort_values('时间')
                    
                    fig_trend = px.line(
                        hourly_df,
                        x='时间',
                        y='错误数量',
                        title="错误发生时间分布",
                        markers=True
                    )
                    st.plotly_chart(fig_trend, use_container_width=True)
            
        except Exception as e:
            st.error(f"❌ 分析错误记录时出错: {str(e)}")
            st.exception(e)